<template>
    <div class="sci-ui-dragging-canvas" style="min-height: 500px; min-width:500px; background-color: aliceblue;">

        <!--作为一个非static布局，与上级元素等大，保证同样大小 
            当元素定义了position：absolute时，如果top, bottom, left, right都没有指定，
            则其left，top值与原文档流位置一致 
            标准详见：https://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width
            因此暂时无需担心这个行为是标准中没有的
            -->
        <div class="pyminer-outer-nonstatic-wrapper">
            <DraggingContainer :ref="createDraggingContainerRefSetter(slotName)" :slotComponentID="slotName"
                v-for="(slotName, index) in slotNames" :key="slotName" v-show="layoutDataInitialized"
                @container-changed="onContainerLayoutChange(slotName, $event)">
                <slot :name="slotName" :layout="containerLayout(slotName)"></slot>
            </DraggingContainer>
        </div>
    </div>
</template>
<style lang="css">
.pyminer-outer-nonstatic-wrapper {
    position: absolute;
}
</style>
<script setup lang="ts">
import { defineProps, onBeforeMount, nextTick, ref, computed, reactive, VNodeRef, VNode } from "vue"
import DraggingContainer from "./DraggingContainer.vue";
import { DraggingLayoutManager, ContainerLayout, LayoutData } from "./dragcontainers"

//计算属性传递参数
const containerLayout = computed(() => (containerName: string) => {
    return draggingLayoutManager.getContainerLayout(containerName)
})
const layoutDataInitialized = ref(false)

const props = defineProps({
    componentName: { type: String, required: true },
    slotNames: { type: Array<string>, required: true }
})

const draggingLayoutManager = reactive(new DraggingLayoutManager(props.componentName, props.slotNames, async (layoutData: LayoutData) => {
    for (const componentName in draggingContainerRefs.value) {
        draggingContainerRefs.value[componentName].updateInitialLayout(draggingLayoutManager.getContainerLayout(componentName))
    }
    layoutDataInitialized.value = true
}))
const draggingContainerRefs = ref<{ [key: string]: InstanceType<typeof DraggingContainer> }>({});

const createDraggingContainerRefSetter = (componentName: string): VNodeRef => {
    return ((component: InstanceType<typeof DraggingContainer>) => {
        if (component) {
            draggingContainerRefs.value[componentName] = component;
        }
    }) as any as VNodeRef;
}

// 更新容器当前的位置
const onContainerLayoutChange = (slotName: string, layout: ContainerLayout) => {
    draggingLayoutManager.updateContainerLayout(slotName, layout);
}
</script>